/* Copyright (c) 2015,2016 Lucky Byte, Inc.
 */
package com.lucky_byte.pay.jar;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.google.gson.JsonObject;

/**
 * 报文抽象类
 */
public abstract class Packet
{
	private static final Logger logger = LogManager.getLogger();

	/**
	 * 判断字段是否存在
	 *
	 * @param name 字段名称
	 * @return 是否存在
	 */
	abstract public boolean has(String name);

	/**
	 * 获取字段的值，不同的报文处理方式不一样
	 *
	 * @param name 字段名称
	 * @return 字符串值或 null
	 */
	abstract public String get(String name);

	/**
	 * 设置字段的值，如果报文没有对应的字段，则会新增一个字段.
	 *
	 * @param name 字段名称
	 * @param value 新值
	 * @return true / false
	 */
	abstract public boolean set(String name, String value);

	/**
	 * 获取报文中的字段数量
	 *
	 * @return 字段数量
	 */
	abstract public int count();

	/**
	 * 返回报文中所有的字段名称集合
	 *
	 * @return 所有字段名称
	 */
	abstract public List<String> keySet();

	/**
	 * 删除一个字段
	 *
	 * @param name 字段名称
	 */
	abstract public void remove(String name);

	/**
	 * 清空报文，所有报文内容都被删除
	 */
	abstract public void clear();

	/**
	 * 克隆报文，新包和原包内容完全相同，但使用不同的内存空间
	 *
	 * @return 新报文对象
	 */
	abstract public Packet clone();

	/**
	 * 将报文转换为一个 json 对象
	 *
	 * @return Json 对象
	 */
	abstract public JsonObject toJson();

	/**
	 * 设置/获取 TPDU，不是所有报文支持 TPDU
	 *
	 * @param tpdu 以字符串形式表示的 TPDU，例如：'6500000200'
	 */
	public boolean setTpdu(String tpdu) {
		logger.error("报文[{}]不支持 TPDU.", getClass().getSimpleName());
		return false;
	}
	public String getTpdu() {
		logger.error("报文[{}]不支持 TPDU.", getClass().getSimpleName());
		return null;
	}

	/**
	 * 设置/获取报文头，不是所有报文支持报文头，并且各种报文的报文头是不一样的，
	 * 请根据接口规范进行设置。
	 *
	 * @param head 以字符串形式表示的报文头，例如：'654000040102'
	 */
	public boolean setHead(String head) {
		logger.error("报文[{}]不支持报文头.", getClass().getSimpleName());
		return false;
	}
	public String getHead() {
		logger.error("报文[{}]不支持报文头.", getClass().getSimpleName());
		return null;
	}

	/**
	 * 设置/获取拨号监控主叫号码
	 * @param ani 以字符串形式表示的主叫号码，例如 '00000000'
	 */
	public boolean setDialANI(String ani) {
		logger.error("报文[{}]不支持拨号信息.", getClass().getSimpleName());
		return false;
	}
	public String getDialANI() {
		logger.error("报文[{}]不支持拨号信息.", getClass().getSimpleName());
		return null;
	}

	/**
	 * 设置/获取拨号监控被叫号码
	 * @param dni 以字符串形式表示的被叫号码，例如 '00000000'
	 */
	public boolean setDialDNI(String dni) {
		logger.error("报文[{}]不支持拨号信息.", getClass().getSimpleName());
		return false;
	}
	public String getDialDNI() {
		logger.error("报文[{}]不支持拨号信息.", getClass().getSimpleName());
		return null;
	}

}
